﻿using com.iot.core.boot;
using com.iot.core.data;
using com.iot.core.data.entity;
using com.iot.core.data.service;
using com.iot.core.exception;
using com.iot.core.infrastructure;
using com.iot.core.manager.id;
using com.iot.ht.Controllers.htmenu.data;
using com.iot.ht.Controllers.htpage.data;
using com.iot.ht.Controllers.htuser.data;
using Icom.iot.core.ext;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace com.iot.ht.Controllers.htpage.service
{
    public class HtPageService : BaseService<HtPage>, IHtPageService
    {       
        readonly IRepository<HtPageAuth> htPageAuthMapper;
        readonly IRepository<HtCtl> htCtlMapper;
        readonly IRepository<HtAction> htActionMapper;
        public HtPageService(IRepository<HtPageAuth> p1,
            IRepository<HtCtl> p2,
            IRepository<HtAction> p3
            ) 
        {
            htPageAuthMapper = p1;
            htCtlMapper = p2;
            htActionMapper = p3;
        }

        public async Task<Page<HtPageDto>> PageAsync(BasePageDtQto qm)
        {
            var DB = BaseMapper.DB;
            var q = BaseMapper.GetAll()
                .Join(DB.Set<HtUser>(),
                    a => new { CrtUid = a.CrtUid  },
                    b => new { CrtUid = b.Id },
                    (a, b) => new
                    {
                        Data = a,

                        CrtUname =b.Name
                    }
                )
                .Join(DB.Set<HtUser>(),
                     a => new { CrtUid = a.Data.EdtUid },
                    b => new { CrtUid = b.Id },
                    (a, b) => new
                    {
                        Data = a.Data,
                        CrtUname = a.CrtUname,
                        EdtUname = b.Name
                    }
                );
            if (!string.IsNullOrEmpty(qm.Key))
            {
                q = q.Where(a => a.Data.Name.Contains(qm.Key)
                || a.Data.Code.Contains(qm.Key)
                
                );
            }
            if (!string.IsNullOrWhiteSpace(qm.Dtb))
            {
                q = q.Where(a => a.Data.CrtDt >= qm.GetDB());
            }
            if (!string.IsNullOrWhiteSpace(qm.Dte))
            {
                q = q.Where(a => a.Data.CrtDt < qm.GetDE());
            }
            var sort = qm.GetSort();
            sort.Filed = "Data." + sort.Filed;

            

            var Total = await q.CountAsync();
            var r = new Page<HtPageDto>(Total, qm.Page, qm.PageSize);

            q = q.OrderBy(sort.Filed, sort.Asc);
            var l = await q.Skip((qm.Page - 1) * qm.PageSize).Take(qm.PageSize).ToListAsync();

            r.Records = new List<HtPageDto>();
            foreach (var m in l)
            {
                var mm = new HtPageDto();
                EntityToDto(m.Data, mm);
                mm.CrtUname = m.CrtUname;
                mm.EdtUname = m.EdtUname; 
                r.Records.Add(mm);
            }
            return r;
        }
        public HtPageDto InsertInit()
        {
            
            var mm = new HtPageDto
            {
                Id=HtIdManager.Current.NextLong(),
                 
                Imgurl= "layui-icon-form", 
            }; 
            return mm;
        }
        public HtPageAuthDto InsertAuthInit()
        {

            var mm = new HtPageAuthDto
            {
                Id = HtIdManager.Current.NextLong(), 
            };
            return mm;
        }

        public async Task<HtPageDto> DetailAsync(BaseQto qm)
        {
            var m = await BaseMapper.GetByIdAsync(qm.Id);
            var mm = new HtPageDto();

            BaseMapper.EntityToDto(m, mm);
            mm.CrtUname = BaseMapper.GetName(m.CrtUid, "htuser");
            mm.EdtUname = BaseMapper.GetName(m.EdtUid, "htuser");

            var ldbauth =await htPageAuthMapper.GetAll()
                .Where(a => a.HtpageId == m.Id)
                .ToListAsync();
            foreach(var mauth in ldbauth)
            {
                var mmauth = new HtPageAuthDto();
                htPageAuthMapper.EntityToDto(mauth, mmauth);
                mm.Auths.Add(mmauth);
            }
              
            return mm;
        }
        public int Insert(HtPageDto mm)
        {
            var mold = BaseMapper.GetAll()
                .Where(a => a.Code == mm.Code)
                .FirstOrDefault();
            if (mold != null)
            {
                throw new MyException("数据重复");
            }

            var m = new HtPage();
            BaseMapper.DtoToEntity(mm, m);
             
            foreach(var masrc in  mm.Auths)
            {
                var madst = new HtPageAuth();
                htPageAuthMapper.DtoToEntity(masrc, madst);
                madst.HtpageId=mm.Id; 
                htPageAuthMapper.Insert(madst, true);
            }

            return  Insert(m);
        }
        public int Update(HtPageDto mm)
        {
            var m = GetById(mm.Id);
            if (m.Code != mm.Code)
            {
                var mold = BaseMapper.GetAll()
                .Where(a => a.Code == mm.Code)
                .FirstOrDefault();
                if (mold != null)
                {
                    throw new MyException("数据重复");
                }

            }             
            BaseMapper.DtoToEntity(mm, m);


            var ldbauth = htPageAuthMapper.GetAll().Where(a => a.HtpageId == mm.Id).ToList();
             
            foreach (var masrc in mm.Auths)
            {
                var madst = ldbauth.Where(a => a.Id == masrc.Id).FirstOrDefault();
                if (masrc == null)
                {
                    madst = new HtPageAuth();
                    htPageAuthMapper.DtoToEntity(masrc, madst);
                    madst.HtpageId = mm.Id;
                    htPageAuthMapper.Insert(madst, true);
                }
                else
                {
                    htPageAuthMapper.DtoToEntity(masrc, madst);
                    htPageAuthMapper.Update(madst, true);
                } 
            }

            foreach(var madb in ldbauth)
            {
                var masrc = mm.Auths.Where(a => a.Id == madb.Id).FirstOrDefault();
                if (masrc == null)
                {
                    htPageAuthMapper.Delete(madb, true);
                }
            }
            return Update(m);
        }

        public HtPageDto InsertInitForCtl(long ctlId)
        {
            var mctl = htCtlMapper.GetById(ctlId);
            var laction = htActionMapper.GetAll()
                .Where(a => a.CtlFullName == mctl.CtlFullName
                &&a.AuthType=="Auth")
                .OrderBy(a => a.Id)
                .ToList();
            var ename = mctl.CtlFullName.Substring(mctl.CtlFullName.LastIndexOf(".") + 1).ToLower();
            if (ename.EndsWith("controller"))
            {
                ename = ename.Substring(0, ename.Length  - 10);
            }
            var mm = new HtPageDto
            {
                Id = HtIdManager.Current.NextLong(),
                Code = "/" + ename + "/index",
                Imgurl = "layui-icon-form",
                Lx = "后台",
                Name = mctl.Name,
                Memo = mctl.Memo,

            };
            var Sortno = 10;
            foreach(var mact in laction)
            {
                var mauth = new HtPageAuthDto
                {
                    Id = HtIdManager.Current.NextLong(),
                    Code = mact.Ename.ToLower(),
                    Name = mact.Name,
                    Memo = mact.Memo,
                    Sortno = Sortno,
                    Urls = mact.FullUrl,

                };
                mm.Auths.Add(mauth);
                Sortno += 10; 
            }
            return mm;
        }
    }
}
